package meta

import (
	"strings"

	"gitee.com/micro-plat/codeless/apiserver/meta/biz/consts"
	"github.com/micro-plat/lib4go/db"
	"github.com/micro-plat/lib4go/errs"
	"github.com/micro-plat/lib4go/types"
)

var funcMap = map[string]func() string{}

func getMetaColumnParam(source, method, param string, isDictLabel, isLikeQuery bool) map[string]interface{} {
	params := map[string]interface{}{
		"fk_column_id":      0,
		"is_auto_increment": false,
		"is_pk":             false,
		"is_fk":             false,
		"is_dict_value":     false,
		"is_dict_label":     types.DecodeInt(isDictLabel, true, 1, 0),
		"is_like_query":     types.DecodeInt(isLikeQuery, true, 1, 0),
		"is_dict_group":     false,
	}
	switch strings.ToUpper(source) {
	case consts.SOURCE_USER_INPUT: //用户输入数据处理
		params["default_value"] = param
	case consts.SOURCE_USER_SELECT: //用户选择列处理
		switch strings.ToUpper(method) {
		case consts.SOURCE_METHOD_TABLE:
			params["is_fk"] = true
		case consts.SOURCE_METHOD_DICT:
			params["is_fk"] = true
		}
	case consts.SOURCE_DB: //数据库
		switch strings.ToUpper(method) {
		case consts.SOURCE_METHOD_AUTO_INCREMENT: //自增,只有组件能自增
			params["is_auto_increment"] = true
			params["is_pk"] = true
			if param != "" {
				params["default_value"] = param
			}
		case consts.SOURCE_METHOD_CURRENT_TIMESTAMP: //时间序列
			iparam := types.GetInt(param, 1)
			if iparam == 1 {
				params["default_value"] = "CURRENT_TIMESTAMP"
			} else {
				params["default_value"] = "CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
			}
		}
	case consts.SOURCE_SYSTEM: //系统
		if m, ok := funcMap[method]; ok {
			params["default_value"] = m()
		}
	}

	return params
}

func getMetaColumnByColumnId(db db.IDBExecuter, tenantID int, columnID int64, oldColumnName ...string) (types.IXMap, error) {
	params := map[string]interface{}{
		"tenant_id": tenantID,
		"column_id": columnID,
	}
	data, err := db.Query(sqlGetColumnByColumnID, params)
	if err != nil {
		return nil, err
	}
	result := colums2TableColumns(data, oldColumnName...)
	return result.Get(0), nil
}
func metaColumnExists(db db.IDBExecuter, tenantID int, tableID int64, columnName string) (bool, error) {
	params := map[string]interface{}{
		"tenant_id": tenantID,
		"table_id":  tableID,
		"name":      columnName,
	}
	value, err := db.Scalar(existsColumn, params)
	if err != nil {
		return false, err
	}
	return types.GetInt(value, 0) > 0, nil
}

// updateMetaColumnByDB 编辑字段元数据
func updateMetaColumnByDB(db db.IDBExecuter, tenantID int, columnID int64, columnTitle, columnName, columnType string, isNullable bool, isDictLabel, isLikeQuery bool, source, method, param string, isPrefab bool, description string) error {
	params := map[string]interface{}{
		"tenant_id":     tenantID,
		"column_id":     columnID,
		"title":         columnTitle,
		"name":          columnName,
		"type":          columnType,
		"source":        source,
		"method":        method,
		"param":         param,
		"is_prefab":     types.DecodeInt(isPrefab, true, 1, 0),
		"is_dict_label": types.DecodeInt(isDictLabel, true, 1, 0),
		"is_like_query": types.DecodeInt(isLikeQuery, true, 1, 0),
		"description":   description,
		"is_nullable":   types.DecodeInt(isNullable, true, 1, 0),
	}

	// 扩展参数
	extparams := getMetaColumnParam(source, method, param, isDictLabel, isLikeQuery)
	for k, v := range extparams {
		params[k] = v
	}
	_, eff, err := db.Executes(sqlUpdateColumn, params)
	if err != nil || eff == 0 {
		return errs.GetDBError(eff, err)
	}
	return nil
}

// addMetaColumnByDB 添加字段元数据
func addMetaColumnByDB(db db.IDBExecuter, tenantID int, tableID int64, columnTitle, columnName, columnType string, isNullable bool, isDictLabel, isLikeQuery bool, source, method, param string, isPrefab bool, description string) (int64, error) {
	params := map[string]interface{}{
		"tenant_id":   tenantID,
		"table_id":    tableID,
		"title":       columnTitle,
		"name":        columnName,
		"type":        columnType,
		"source":      source,
		"method":      method,
		"param":       param,
		"is_prefab":   isPrefab,
		"description": description,
		"is_nullable": isNullable,
	}

	// 扩展参数
	extparams := getMetaColumnParam(source, method, param, isDictLabel, isLikeQuery)
	for k, v := range extparams {
		params[k] = v
	}

	id, eff, err := db.Executes(sqlInsertColumn, params)
	if err != nil || eff == 0 {
		return 0, errs.GetDBError(eff, err)
	}
	return id, nil
}
